<template>
  <div class="RulesBox">
    <a-table ref="RulesTables" id="RulesTable" :columns="columns" :data-source="data" bordered>
      <template slot="footer">
        <div class="Topchang" :style="topchangStyle"></div>
        <div class="Bottomchang" :style="bottomchangStyle"></div>
        <div class="Leftchang" :style="lefkuangStyle"></div>
        <div class="Rightchang" :style="rightkuangStyle"></div>
        <div class="Heightlight" :style="heightlightStyle"></div>
        <!-- <div class="choosebackground" :style="choosebackgroundStyle"></div> -->
        <!-- 鼠标右键组件 -->
        <div class="contextMeun" :style="contextMeumStyle" v-if="showContextMeun">
          <div @click="HandleconteMeum">
            <li data-id="merge" class="li-style">
              {{ mergeTitle === 'merge' ? "合并" :
              mergeTitle === 'Rowmerge' ? "纵向合并" :
              mergeTitle === 'Colmerge' ? '横向合并' :
              "取消合并" }}
            </li>
            <li data-id="copy" class="li-style">复制</li>
            <li class="li-style">删除</li>
          </div>
        </div>
      </template>
    </a-table>
  </div>
</template>
<script>
// In the fifth row, other columns are merged into first column
// by setting it's colSpan to be 0
// const renderContent =
const data = [
  {
    key: '1',
    name: 'John Brown2',
    age: 322,
    tel: '0571-220989092',
    phone: 188898989892,
    address: 'New York No. 1 Lake Park2',
  },
  {
    key: '2',
    name: 'Jim Green',
    tel: '0571-22098333',
    phone: 18889898888,
    age: 42,
    address: 'London No. 1 Lake Park',
  },
  {
    key: '3',
    name: 'Joe Black',
    age: 32,
    tel: '0575-22098909',
    phone: 18900010002,
    address: 'Sidney No. 1 Lake Park',
  },
  {
    key: '4',
    name: 'Jim Red',
    age: 18,
    tel: '0575-22098909',
    phone: 18900010002,
    address: 'London No. 2 Lake Park',
  },
  {
    key: '5',
    name: 'Jake White',
    age: 18,
    tel: '0575-22098909',
    phone: 18900010002,
    address: 'Dublin No. 2 Lake Park',
  },
]

export default {
  props: ['tabledemo'],
  data() {
    const customRender = (text, row, index) => {
      return (
        <div
          style={{ padding: '16px' }}
          onMousedown={(e) => this.onMousedown(e, index, row, text)}
          onMousemove={(e) => this.onMousemove(e, index, row, text)}
          onMouseup={(e) => this.onMouseup(e, index)}
        >
          {text}
        </div>
      )
    }
    const columns = [
      {
        title: 'Name2',
        dataIndex: 'name',
        customRender: customRender,
        customCell: (record, index) => {
          if (index === 0) {
            return {
              attrs: {
                colSpan: 2,
              },
            }
          }
        },
      },
      {
        title: 'Age2',
        dataIndex: 'age',
        customRender: customRender,
        customCell: (record, index) => {
          if (index === 0) {
            return {
              style: {
                display: 'none',
              },
            }
          }
        },
      },
      {
        title: 'Home phone2',
        // colSpan: 2,
        dataIndex: 'tel',
        customRender: customRender,
      },
      {
        title: 'Phone2',
        // colSpan: 0,
        dataIndex: 'phone',
        customRender: customRender,
      },
      {
        title: 'Address',
        dataIndex: 'address',
        customRender: customRender,
      },
    ]
    return {
      data,
      columns,
      showContextMeun: false,
      // 鼠标右键点击的坐标
      ContextMeunX: 0,
      ContextMeunY: 0,
      // 第一次点击的index
      firstIndex: 0,
      // // 最后点击的index
      lastIndex: 0,
      // 表格的key值
      tableKey: '',
      tableKeys: [],
      tdWidth: 0,
      tdHeight: 0,
      mergeTitle: '',
      // 线坐标
      clientStle: {
        start: false,
        top: '',
        left: '',
        width: '',
        height: '',
      },
    }
  },
  created() {},
  mounted() {
    console.log('ref', this.$refs, this.tabledemo.init(this))
    this.$refs.RulesTables.$el.addEventListener('contextmenu', (e) => {
      e.preventDefault()
    })
  },
  beforeDestroy() {
    this.$refs.RulesTables.$el.removeEventListener('contextmenu', (e) => {
      e.preventDefault()
    })
  },
  computed: {
    //  鼠标右键
    contextMeumStyle() {
      return {
        position: 'absolute',
        left: this.ContextMeunX + 'px',
        top: this.ContextMeunY + 'px',
        width: '100px',
        height: '100px',
        background: '#fff',
        display: 'flex',
        justifyContent: 'center',
        alignItems: 'center',
        zIndex: 1000,
        borderRadius: '5px',
      }
    },

    // 选中样式
    // choosebackgroundStyle() {
    //   return {
    //     position: 'absolute',
    //     background: 'red',
    //     top: this.clientStle.top + 'px',
    //     left: this.clientStle.left + 'px',
    //     width: this.clientStle.width + 'px',
    //     height: this.clientStle.height + 'px',
    //   }
    // },

    topchangStyle() {
      return {
        position: 'absolute',
        background: 'green',
        top: this.clientStle.top + 'px',
        left: this.clientStle.left + 'px',
        width: this.clientStle.width + 'px',
        height: '1px',
      }
    },
    bottomchangStyle() {
      return {
        position: 'absolute',
        background: 'green',
        top: this.clientStle.top + this.clientStle.height + 'px',
        left: this.clientStle.left + 'px',
        width: this.clientStle.width + 'px',
        height: '1px',
      }
    },
    lefkuangStyle() {
      return {
        position: 'absolute',
        background: 'green',
        top: this.clientStle.top + 'px',
        left: this.clientStle.left + 'px',
        width: '1px',
        height: this.clientStle.height + 'px',
      }
    },
    rightkuangStyle() {
      return {
        position: 'absolute',
        background: 'green',
        top: this.clientStle.top + 'px',
        left: this.clientStle.left + this.clientStle.width + 'px',
        width: '1px',
        height: this.clientStle.height + 'px',
      }
    },
    // 表格高亮
    heightlightStyle() {},
  },
  methods: {
    // 纵向合并
    customCell(recod, index, firstIndex, lastIndex, oldCustomCell) {
      const oldCustomCells = oldCustomCell && oldCustomCell(recod, index)
      console.log('oldCustomCells', oldCustomCells, index, firstIndex)
      if (index === firstIndex) {
        return {
          attrs: {
            ...oldCustomCells?.attrs,
            rowSpan: lastIndex - firstIndex + 1,
          },
        }
      }
      if (index <= lastIndex && index > firstIndex) {
        return {
          style: {
            ...oldCustomCells?.style,
            display: 'none',
          },
        }
      }
      if (oldCustomCells) {
        return oldCustomCells
      }
    },

    // 取消纵向合并
    cacelCell(recod, index, rowIndex, rowspan, oldCustomCell) {
      const oldCustomCells = oldCustomCell && oldCustomCell(recod, index)
      console.log('oldCustomCells', oldCustomCells, index, rowIndex)
      if (index === rowIndex) {
        return {
          attrs: {
            ...oldCustomCells?.attrs,
            rowSpan: null,
          },
        }
      }
      if (index > rowIndex && index < rowIndex + Number(rowspan)) {
        return {
          style: {
            // ...oldCustomCells?.style,
            display: null,
          },
        }
      }
      if (oldCustomCells) {
        return oldCustomCells
      }
    },
    /**纵向合并数据
     * @param {Object} columns 表格列配置
     * @param {Number} firstColIndex 合并的列的开始index
     * @param {Number} lastColIndex 合并的列的结束index
     * @param {string} tableKey 合并的列的key
     */
    RowmergeData({ columns, firstColIndex, lastColIndex, tbaleKey }) {
      console.log('rowmer', columns, firstColIndex, lastColIndex, tbaleKey)
      return columns.map((item, index) => {
        if (item.dataIndex === tbaleKey) {
          return {
            ...item,
            customCell: (recod, index) => {
              return this.customCell(recod, index, firstColIndex, lastColIndex, item.customCell)
            },
          }
        }
        return item
      })
    },

    /**
     * 取消纵向合并数据
     * @param {Object} columns 表格列配置
     * @param {Number} firstColIndex 取消合并的列的开始index
     * @param {string} tableKey 取消合并的列的key
     * @param {Number} rowSpan 占据的列数
     */
    RowcacelmergeData({ columns, firstColIndex, tableKey, rowSpan }) {
      return columns.map((item, index) => {
        if (item.dataIndex === tableKey) {
          return {
            ...item,
            customCell: (recod, index) => {
              return this.cacelCell(recod, index, firstColIndex, rowSpan, item.customCell)
            },
          }
        }
        return item
      })
    },

    // 调整tableKeys中的顺序
    sortTableKeys(columns, tableKeys) {
      // 判断tableKeys中值是否都在columns中
      const columnsSet = new Set(columns.map((item) => item.dataIndex))
      if (!tableKeys.every((item) => columnsSet.has(item))) {
        throw new Error('tableKeys have value is not in columns')
      }
      // 排序
      const sortTableKeys = tableKeys.sort((a, b) => {
        return columns.findIndex((item) => item.dataIndex === a) - columns.findIndex((item) => item.dataIndex === b)
      })
      // 判断tableKeys是否连续
      const startIndex = columns.findIndex((item) => item.dataIndex === sortTableKeys[0])
      const endIndex = columns.findIndex((item) => item.dataIndex === sortTableKeys[sortTableKeys.length - 1])
      const splitColums = columns.map((item) => item.dataIndex).filter((item, index) => index >= startIndex && index <= endIndex)
      if (!(splitColums[0] === sortTableKeys[0] && splitColums[splitColums.length - 1] === sortTableKeys[sortTableKeys.length - 1])) {
        throw new Error('tableKeys is not continuous')
      }
      return sortTableKeys
    },

    // 横向合并
    RowcustomCell(recod, index, ColIndex, oldCustomCell, colSpan) {
      const oldCustomCells = oldCustomCell && oldCustomCell(recod, index)
      if (index === ColIndex) {
        if (colSpan) {
          // console.log('====', (oldCustomCells?.attrs.colSpan ?? 0) + ((oldCustomCells?.attrs.colSpan ?? 0) - colSpan) + 1)
          // const colspan = oldCustomCells?.attrs?.colSpan
          //   ? Math.abs(oldCustomCells?.attrs?.colSpan + oldCustomCells?.attrs.colSpan - colSpan + 1)
          //   : colSpan
          const colspan = colSpan
          return {
            attrs: {
              ...oldCustomCells?.attrs,
              colSpan: colspan,
            },
          }
        } else {
          return {
            style: {
              ...oldCustomCells?.style,
              display: 'none',
            },
          }
        }
      }
      if (oldCustomCells) {
        return oldCustomCells
      }
    },

    /**
     * 横向合并数据
     * @param {Object} columns 表格列配置
     * @param {Number} ColIndex 合并的列的index
     * @param {Arary} tableKeys 合并的列的key
     */
    ColmergeData({ columns, ColIndex, tableKeys }) {
      tableKeys = this.sortTableKeys(columns, tableKeys)
      const len = tableKeys.length
      console.log('tableKeys', len)
      return columns.map((item, index) => {
        if (item.dataIndex === tableKeys[0]) {
          return {
            ...item,
            customCell: (recod, index) => {
              return this.RowcustomCell(recod, index, ColIndex, item.customCell, len)
            },
          }
        } else if (tableKeys.includes(item.dataIndex)) {
          return {
            ...item,
            customCell: (recod, index) => {
              return this.RowcustomCell(recod, index, ColIndex, item.customCell)
            },
          }
        }
        return item
      })
    },

    // 取消横向合并
    cacelRowcustomCell(recod, index, ColIndex, oldCustomCell, type) {
      const oldCustomCells = oldCustomCell && oldCustomCell(recod, index)
      if (index === ColIndex) {
        if (type) {
          return {
            attrs: {
              ...oldCustomCell?.attrs,
              colSpan: null,
            },
          }
        } else {
          return {
            style: {
              // ...oldCustomCells?.style,
              display: null,
            },
          }
        }
      }
      if (oldCustomCells) {
        return oldCustomCells
      }
    },

    /**
     * 取消横向合并数据
     * @param {Object} columns 表格列配置
     * @param {Number} ColIndex 取消合并的列的index
     * @param {string} tableKey 取消合并key
     * @param {Number} colSpan 取消合并的列的colSpan
     *
     */
    ColcacelmergeData({ columns, tableKey, ColIndex, colSpan }) {
      let firstIndex = 999
      console.log('-----', columns, tableKey, ColIndex, colSpan)
      return columns.map((element, index) => {
        if (element.dataIndex === tableKey) {
          firstIndex = index
          return {
            ...element,
            customCell: (recod, index) => {
              return this.cacelRowcustomCell(recod, index, ColIndex, element.customCell, true)
            },
          }
        }
        console.log('element', firstIndex, index, colSpan)
        if (index > firstIndex && index < firstIndex + Number(colSpan)) {
          return {
            ...element,
            customCell: (recod, index) => {
              return this.cacelRowcustomCell(recod, index, ColIndex, element.customCell, false)
            },
          }
        }
        return element
      })
    },

    /**
     * 整体合并数据
     * @param {Object} columns 表格列配置
     * @param {Number} firstIndex 合并的列的开始index
     * @param {Number} lastIndex 合并的列的结束index
     * @param {string} tableKey 合并的列的key
     * @param {Arary} tableKeys 合并的列的key
     */
    mergeDataAll({ columns, firstIndex, lastIndex, tableKey, tableKeys }) {
      let selfColumns = columns
      Array.from({ length: lastIndex - firstIndex + 1 }, (item, index) => {
        console.log('index', index)
        selfColumns = this.ColmergeData({
          columns: selfColumns,
          ColIndex: firstIndex + index,
          tableKeys: tableKeys,
        })
      })
      selfColumns = this.RowmergeData({
        columns: selfColumns,
        firstColIndex: firstIndex,
        lastColIndex: lastIndex,
        tbaleKey: tableKey,
      })
      return selfColumns
    },

    // 取消整体合并customcell
    cacelRowcustomCellAll(recod, index, Index, rowspan, oldCustomCell, type) {
      const oldCustomCells = oldCustomCell && oldCustomCell(recod, index)
      if (index === Index) {
        if (type) {
          return {
            attrs: {
              ...oldCustomCell?.attrs,
              colSpan: null,
            },
          }
        } else {
          return {
            style: {
              // ...oldCustomCells?.style,
              display: null,
            },
          }
        }
      }
      if (index > Index && index < Index + Number(rowspan)) {
        return {
          style: {
            // ...oldCustomCells?.style,
            display: null,
          },
        }
      }
      if (oldCustomCells) {
        return oldCustomCells
      }
    },

    /**
     * 整体取消合并
     * @param {Object} columns 表格列配置
     * @param {Number} firstIndex 合并的列的开始index
     * @param {string} tableKey 合并的列的key
     * @param {number} rowSpan 占据的列数
     * @param {number} colSpan 占据的行数
     */
    mergecacelAll({ columns, Index, tableKey, rowSpan, colSpan }) {
      let firstIndex = 999
      return columns.map((element, index) => {
        if (element.dataIndex === tableKey) {
          firstIndex = index
          return {
            ...element,
            customCell: (recod, index) => {
              return this.cacelRowcustomCellAll(recod, index, Index, rowSpan, element.customCell, true)
            },
          }
        }
        if (index > firstIndex && index < firstIndex + Number(colSpan)) {
          return {
            ...element,
            customCell: (recod, index) => {
              return this.cacelRowcustomCellAll(recod, index, Index, rowSpan, element.customCell, false)
            },
          }
        }
        return element
      })
    },

    // 获取父组件
    getParentElement(e) {
      const paraentElement = e.target.parentElement
      // 获取父元素的左上的坐标
      const offsetLeft = paraentElement.offsetLeft
      const offsetTop = paraentElement.offsetTop
      // 获取父元素的宽高
      const offsetWidth = paraentElement.offsetWidth
      const offsetHeight = paraentElement.offsetHeight
      return { paraentElement, offsetLeft, offsetTop, offsetWidth, offsetHeight }
    },

    // 重置数据
    clearData() {
      this.showContextMeun = false
      this.clientStle = {
        start: false,
        top: 0,
        left: 0,
        width: 0,
        height: 0,
      }
      this.firstIndex = 0
      this.lastIndex = 0
      this.tableKey = ''
      this.mergeTitle = ''
      this.tableKeys = []
      this.tdWidth = 0
      this.tdHeight = 0
      this.tdTop = 0
      this.tdLeft = 0
      this.rowSpan = 0
      this.colSpan = 0
    },

    // 右键事件
    HandleconteMeum(e) {
      const id = e.target.dataset.id
      console.log('id', id)
      if (id === 'merge') {
        console.log('colu', this.mergeTitle, this.columns, this.firstIndex, this.lastIndex)
        let columns = this.columns
        if (this.mergeTitle === 'Rowmerge') {
          columns = this.RowmergeData({
            columns: this.columns,
            firstColIndex: this.firstIndex,
            lastColIndex: this.lastIndex,
            tbaleKey: this.tableKey,
          })
        } else if (this.mergeTitle === 'Colmerge') {
          columns = this.ColmergeData({
            columns: this.columns,
            ColIndex: this.firstIndex,
            tableKeys: this.tableKeys,
          })
        } else if (this.mergeTitle === 'merge') {
          columns = this.mergeDataAll({
            columns: this.columns,
            firstIndex: this.firstIndex,
            lastIndex: this.lastIndex,
            tableKey: this.tableKey,
            tableKeys: this.tableKeys,
          })
        } else if (this.mergeTitle === 'rowcancel') {
          console.log('rowcancel')
          columns = this.RowcacelmergeData({
            columns: this.columns,
            firstColIndex: this.firstIndex,
            tableKey: this.tableKey,
            rowSpan: this.rowSpan,
          })
        } else if (this.mergeTitle === 'colcancel') {
          console.log('colcancel')
          columns = this.ColcacelmergeData({
            columns: this.columns,
            ColIndex: this.firstIndex,
            tableKey: this.tableKey,
            colSpan: this.colSpan,
          })
        } else if (this.mergeTitle === 'mergecancel') {
          console.log('mergecancel')
          columns = this.mergecacelAll({
            columns: this.columns,
            Index: this.firstIndex,
            tableKey: this.tableKey,
            rowSpan: this.rowSpan,
            colSpan: this.colSpan,
          })
        }
        this.columns = columns
        this.clearData()
        console.log('合并')
      } else if (id === 'copy') {
        this.ColmergeData({
          columns: this.columns,
          ColIndex: this.firstIndex,
          tableKeys: ['age', 'name', 'phon'],
        })
        this.columns = console.log('复制')
      } else {
        console.log('删除')
      }
    },

    onMousedown(e, index, row, text) {
      console.log('onMousedown', e, this.firstIndex)
      // 获取父元素
      const { layerX, layerY } = e
      // 判断是否为鼠标左键按下
      if (e.button === 0) {
        this.getParentElements = this.getParentElement(e)
        const { offsetLeft, offsetTop, offsetWidth, offsetHeight } = this.getParentElement(e)
        this.tableKeys = []
        this.showContextMeun = false
        this.firstIndex = index
        this.tableKey = Object.keys(row).find((item) => row[item] === text)
        console.log('鼠标左键按下', this.tableKey)
        this.tdWidth = offsetWidth
        this.tdHeight = offsetHeight
        this.tdTop = offsetTop
        this.tdLeft = offsetLeft
        this.clientStle = {
          start: true,
          top: offsetTop,
          left: offsetLeft,
          width: offsetWidth,
          height: offsetHeight,
        }
      } else if (e.button === 2 && layerX <= this.clientStle.left + this.clientStle.width && layerY <= this.clientStle.top + this.clientStle.height) {
        const { paraentElement, offsetLeft, offsetTop, offsetWidth, offsetHeight } = this.getParentElements
        // 判断是否为鼠标右键按下
        console.log('e', paraentElement)
        this.showContextMeun = true
        // 设置鼠标右键点击的坐标
        this.ContextMeunX = layerX
        this.ContextMeunY = layerY
        // 获取父元素的attrs
        const attrs = paraentElement.attributes
        console.log('鼠标右键按下', attrs)
        const rowSpan = attrs['rowSpan']?.value
        const colSpan = attrs['colSpan']?.value
        console.log('rowSpan', rowSpan, colSpan, this.clientStle, this.tdWidth, this.tdHeight, this.tableKeys)
        if (colSpan > 1 && rowSpan > 1 && this.clientStle.width === this.tdWidth && this.clientStle.height === this.tdHeight) {
          this.rowSpan = rowSpan
          this.colSpan = colSpan
          this.mergeTitle = 'mergecancel'
        } else if (rowSpan > 1 && this.clientStle.width === this.tdWidth && this.clientStle.height === this.tdHeight) {
          this.rowSpan = rowSpan
          this.mergeTitle = 'rowcancel'
        } else if (colSpan > 1 && this.clientStle.width === this.tdWidth && this.clientStle.height === this.tdHeight) {
          this.colSpan = colSpan
          this.mergeTitle = 'colcancel'
        } else if ((this.clientStle.height > this.tdHeight && this.clientStle.width > this.tdWidth) || (rowSpan > 1 && colSpan > 1)) {
          this.mergeTitle = 'merge'
        } else if (this.clientStle.height > this.tdHeight && this.clientStle.width === this.tdWidth) {
          this.mergeTitle = 'Rowmerge'
        } else if (this.clientStle.width > this.tdWidth && this.clientStle.height === this.tdHeight) {
          this.mergeTitle = 'Colmerge'
        } else {
          this.showContextMeun = false
        }
      }
    },
    // 鼠标移动事件
    onMousemove(e, index, row, text) {
      // 获取父元素
      const { paraentElement, offsetLeft, offsetTop, offsetWidth, offsetHeight } = this.getParentElement(e)
      if (this.clientStle.start) {
        const tableKeys = Object.keys(row).find((item) => row[item] === text)
        this.tableKeys = Array.from(new Set([...this.tableKeys, tableKeys]))
        console.log('-----', offsetLeft, this.tdLeft, this.tdTop, offsetTop)
        if (this.tdLeft > offsetLeft && this.tdTop > offsetTop) {
          this.clientStle = {
            ...this.clientStle,
            width: Math.abs(this.tdLeft - offsetLeft + this.tdWidth),
            left: offsetLeft,
            height: Math.abs(this.tdTop - offsetTop),
            top: offsetTop,
          }
        } else if (this.tdLeft > offsetLeft) {
          this.clientStle = {
            ...this.clientStle,
            width: Math.abs(this.tdLeft - offsetLeft + this.tdWidth),
            height: Math.abs(offsetTop + offsetHeight - this.clientStle.top),
            left: offsetLeft,
          }
        } else if (this.tdTop > offsetTop) {
          this.clientStle = {
            ...this.clientStle,
            height: Math.abs(this.tdTop - offsetTop),
            width: Math.abs(offsetLeft + offsetWidth - this.clientStle.left),
            top: offsetTop,
          }
        } else {
          this.clientStle = {
            ...this.clientStle,
            width: Math.abs(offsetLeft + offsetWidth - this.clientStle.left),
            height: Math.abs(offsetTop + offsetHeight - this.clientStle.top),
          }
        }
      }
    },
    // 鼠标抬起事件
    onMouseup(e, index) {
      if (e.button === 2) {
        return
      }
      this.lastIndex = index
      console.log('onMouseup', index, this.lastIndex)
      this.clientStle = {
        ...this.clientStle,
        start: false,
      }
    },
  },
}
</script>
<style>
#RulesTable {
  position: relative;
}
#RulesTable .ant-table-tbody > tr > td {
  padding: 0;
}
#RulesTable .ant-table-footer {
  padding: 0;
  position: static;
}
#RulesTable .ant-table-body {
  user-select: none;
}
.RulesBox .li-style {
  list-style: none;
  padding: 5px 0;
  cursor: pointer;
}
</style>
